home *** CD-ROM | disk | FTP | other *** search
/ MacFormat 1995 May / macformat-024.iso / Shareware City / Developers / nshellmegasource1.50 / mega src / commands / yesno.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-08-30  |  6.8 KB  |  285 lines  |  [TEXT/KAHL]

  1. /* ========== the commmand file: ==========
  2.  
  3.     yesno.c
  4.     
  5.     Copyright (c) 1993,1994 Newport Software Development
  6.     
  7.     You may distribute unmodified copies of this file for
  8.     noncommercial purposes.  You may use this file as a
  9.     reference when writing your own nShell(tm) commands.
  10.     
  11.     All other rights are reserved.
  12.     
  13.    ========== the commmand file: ========== */
  14.  
  15. #ifdef __MWERKS__            // CodeWarrior requires an A4 setup
  16. #include <A4Stuff.h>
  17. #endif
  18.  
  19. #include "nshc.h"
  20. #include "str_utl.proto.h"
  21. #include "nshc_utl.proto.h"
  22.  
  23. /* ======================================== */
  24.  
  25. // our data record, NewHandled and attached to nshc_parms->data
  26.  
  27. typedef struct {
  28.  
  29.     Str255    theString;        // theString we are receiving fromthe keyboard
  30.     int        overrun;        // non-zero if theString has exceeded 255 chars
  31.     int        stdin;            // non-zero if we input from stdin
  32.  
  33. } t_yesno_data;
  34.  
  35. typedef t_yesno_data **t_yesno_handle;
  36.  
  37. /* ======================================== */
  38.  
  39. // prototypes - for local use only
  40.  
  41. void yesno_by_parameters( t_nshc_parms *nshc_parms, t_nshc_calls *nshc_calls );
  42. void yesno_collect( t_nshc_parms *nshc_parms, t_nshc_calls *nshc_calls );
  43. void yesno_continue( t_nshc_parms *nshc_parms, t_nshc_calls *nshc_calls );
  44. void yesno_getchar( t_nshc_parms *nshc_parms, t_nshc_calls *nshc_calls );
  45. void yesno_print( t_nshc_parms *nshc_parms, t_nshc_calls *nshc_calls );
  46. void yesno_start( t_nshc_parms *nshc_parms, t_nshc_calls *nshc_calls );
  47. void yesno_stop( t_nshc_parms *nshc_parms );
  48.  
  49. /* ======================================== */
  50.  
  51. // if the user put his text on the command line, do it all in one operation
  52.  
  53. void yesno_print( t_nshc_parms *nshc_parms, t_nshc_calls *nshc_calls )
  54. {
  55.     int                size;
  56.     int                lastchar;
  57.     t_yesno_handle    ndata;
  58.     
  59.     ndata = (t_yesno_handle)(nshc_parms->data);
  60.         
  61.     HLock( (Handle)ndata );
  62.     
  63.     size = (**ndata).theString[0];
  64.     
  65.     if (size) {
  66.         nshc_calls->NSH_putStr( (**ndata).theString );
  67.         lastchar = (**ndata).theString[size];
  68.         if ((lastchar == '\r') || (lastchar == ' '))
  69.             nshc_calls->NSH_puts("(y/n): ");
  70.         else
  71.             nshc_calls->NSH_puts(" (y/n): ");
  72.         }
  73.     else
  74.         nshc_calls->NSH_puts("(y/n): ");
  75.         
  76.     HUnlock( (Handle)ndata );
  77. }
  78.  
  79. /* ======================================== */
  80.  
  81. // if the user put his text on the command line, do it all in one operation
  82.  
  83. void yesno_by_parameters( t_nshc_parms *nshc_parms, t_nshc_calls *nshc_calls )
  84. {
  85.     int                arg;
  86.     int                got_one;
  87.     int                length;
  88.     char            *p;
  89.     Str255            localString;
  90.     t_yesno_handle    ndata;
  91.     
  92.     nshc_parms->result = NSHC_NO_ERR;
  93.     nshc_parms->action = nsh_continue;
  94.             
  95.     ndata = (t_yesno_handle)(nshc_parms->data);
  96.             
  97.     arg = 1;
  98.     got_one = 0;
  99.     length = 0;
  100.     localString[0] = 0;
  101.     
  102.     while ( arg < nshc_parms->argc ) {
  103.         if ( nshc_is_operand( nshc_parms, arg) ) {
  104.             p = &nshc_parms->arg_buf[nshc_parms->argv[arg]];
  105.             length += cStrLen(p);
  106.             if (length < 255) {
  107.                 if (got_one)
  108.                     localString[++localString[0]] = ' ';
  109.                 pStrAppendC( localString, p );
  110.                 }
  111.             got_one = 1;
  112.             }
  113.         arg++;
  114.         }
  115.         
  116.     if (length > 255) {
  117.             nshc_calls->NSH_putStr_err("\pyesno: stdin exceeds 255 chars.\r");
  118.             nshc_parms->result = NSHC_ERR_GENERAL;
  119.             nshc_parms->action = nsh_stop;
  120.             }
  121.         else
  122.             if (length) {
  123.                 HLock( (Handle)ndata );
  124.                 pStrCopy( (**ndata).theString, localString );
  125.                 HUnlock( (Handle)ndata );
  126.                 yesno_print( nshc_parms, nshc_calls );
  127.                 }
  128.             else
  129.                 nshc_calls->NSH_puts("(y/n): ");
  130.         
  131. }
  132.  
  133. /* ======================================== */
  134.  
  135. // this _continue routine is used to pick up input from stdin, it loops until
  136. // an end-of-input is found. It posts the input text if it does not exceed 255
  137. // characters, otherwise it posts an error message.  If input exceeds 255 chars,
  138. // all extra chars are eaten.
  139.  
  140. void yesno_collect( t_nshc_parms *nshc_parms, t_nshc_calls *nshc_calls )
  141. {
  142.     int        value;
  143.     int        size;
  144.     Str255    localString;
  145.     
  146.     t_yesno_handle    ndata;
  147.     
  148.     ndata = (t_yesno_handle)(nshc_parms->data);
  149.         
  150.     HLock( (Handle)ndata );
  151.     
  152.     value = nshc_calls->NSH_getStr( localString );
  153.     
  154.     if (value) {
  155.         size = localString[0] + (**ndata).theString[0];
  156.         if (size > 255) (**ndata).overrun = 1;
  157.         if (!(**ndata).overrun) pStrAppend( (**ndata).theString, localString );
  158.         }
  159.         
  160.     HUnlock( (Handle)ndata );
  161.         
  162.     if (value == -1) {
  163.     
  164.         if ((**ndata).overrun) {
  165.             nshc_calls->NSH_putStr_err("\pyesno: stdin exceeds 255 chars.\r");
  166.             nshc_parms->result = NSHC_ERR_GENERAL;
  167.             }
  168.         else {
  169.             yesno_print( nshc_parms, nshc_calls );
  170.             nshc_parms->result = NSHC_NO_ERR;
  171.             }
  172.             
  173.         (**ndata).stdin = 0;    
  174.         }
  175. }
  176.  
  177. /* ======================================== */
  178.  
  179. void yesno_getchar( t_nshc_parms *nshc_parms, t_nshc_calls *nshc_calls )
  180. {
  181.     switch ( nshc_calls->NSH_getchar() ) {
  182.         case 'y':
  183.         case 'Y':                                    // affirmative
  184.             nshc_calls->NSH_putchar('\r');
  185.             nshc_parms->action = nsh_stop;
  186.             nshc_parms->result = 0;
  187.             break;
  188.         case 'n':
  189.         case 'N':                                    // negative
  190.             nshc_calls->NSH_putchar('\r');
  191.             nshc_parms->action = nsh_stop;
  192.             nshc_parms->result = 1;
  193.             break;
  194.         case '\0':                                    // null when no keys pressed
  195.             break;
  196.         case -1:                                    // bail if end of input is found
  197.             nshc_parms->action = nsh_stop;
  198.             nshc_parms->result = -1;
  199.             break;
  200.         default:
  201.             nshc_calls->NSH_putchar('\r');
  202.             yesno_print( nshc_parms, nshc_calls ); // huh?
  203.             break;
  204.         }
  205. }
  206.  
  207. /* ======================================== */
  208.  
  209. // state machine start
  210.  
  211. void yesno_start( t_nshc_parms *nshc_parms, t_nshc_calls *nshc_calls )
  212. {
  213.     t_yesno_handle    ourData;
  214.  
  215.     ourData = (t_yesno_handle)NewHandle( sizeof(t_yesno_data) );
  216.  
  217.     if (ourData) {
  218.         (**ourData).theString[0] = 0;
  219.         (**ourData).overrun = 0;
  220.         (**ourData).stdin = nshc_got_option( nshc_parms, 'i' );
  221.         nshc_parms->data = (Handle)ourData;
  222.         nshc_parms->action = nsh_continue;
  223.         if (!(**ourData).stdin)
  224.             yesno_by_parameters( nshc_parms, nshc_calls );
  225.         }
  226.     else {
  227.         nshc_calls->NSH_putStr_err("\pyesno: Could not allocate storage.\r");
  228.         nshc_parms->result = NSHC_ERR_MEMORY;
  229.         nshc_parms->action = nsh_idle;
  230.         }
  231. }
  232.  
  233. /* ======================================== */
  234.  
  235. // state machine continue
  236.  
  237. void yesno_continue( t_nshc_parms *nshc_parms, t_nshc_calls *nshc_calls )
  238. {
  239.     if ((**(t_yesno_handle)(nshc_parms->data)).stdin)
  240.         yesno_collect(nshc_parms,nshc_calls);
  241.     else
  242.         yesno_getchar(nshc_parms,nshc_calls);
  243. }
  244.  
  245. /* ======================================== */
  246.  
  247. // state machine stop
  248.  
  249. void yesno_stop( t_nshc_parms *nshc_parms )
  250. {        
  251.     if (nshc_parms->data)
  252.         DisposeHandle(nshc_parms->data);
  253.  
  254.     nshc_parms->action = nsh_idle;
  255. }
  256.  
  257. /* ======================================== */
  258.  
  259. void main(t_nshc_parms *nshc_parms, t_nshc_calls *nshc_calls)
  260. {
  261. #ifdef __MWERKS__
  262.     long oldA4  = SetCurrentA4();
  263. #endif
  264.     
  265.     if ( !nshc_bad_version( nshc_parms, nshc_calls, NSHC_VERSION ) ) {
  266.         
  267.         switch (nshc_parms->action) {
  268.             case nsh_start:
  269.                 yesno_start(nshc_parms,nshc_calls);
  270.                 break;
  271.             case nsh_continue:
  272.                 yesno_continue(nshc_parms,nshc_calls);
  273.                 break;
  274.             default:
  275.                 yesno_stop(nshc_parms);
  276.                 break;
  277.             }
  278.             
  279.         }
  280.  
  281. #ifdef __MWERKS__
  282.     SetA4(oldA4);
  283. #endif
  284. }
  285.